package com.qf.web.servlet;


import com.qf.utils.StringConstans;
import com.qf.utils.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;

/**
 * Create by 周志豪 on 2022/8/16  20:45
 *
 * @authoe 周志豪
 * @veision 1.0
 * //TODO  想好了再去做
 * @since 1.0
 */
@WebServlet(urlPatterns = "/")
public class BaseServlet extends HttpServlet {

    private HashMap<String, Object> url2ServletMapping = new HashMap<>();


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String uri = req.getRequestURI();
        //我们约定过uri是servlet名字的前缀
        uri = uri.replace("/", "");
        char c = uri.charAt(0);//获取到首字母
        //转成大写
        uri = uri.replace(c, (char) (c - 32));
        //拼接类名
        String servletName = this.getClass().getPackage().getName() + "." + uri + "Servlet";
        //反射得到class对象
        try {
            Class<?> targetServletClass = Class.forName(servletName);
            //获取到请求的方法名
            String method = req.getParameter("method");
            //如果没有传递method,我们约定就用一个默认方法来执行 比如叫defaultMethod
            if (StringUtils.isEmpty(method)) {
                //代表没有传递方法,根据我们的约定,来处理,比如返回404或者使用默认的方法名
                method = "defaultMethod";
            }
            //获取到Method对象,从我们想要执行的servlet中获取,我们传递的参数就是request和response
            Method targetServletClassMethod = targetServletClass.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
            //执行方法,我们不需要每次都创建一个新的对象,所以只需要创建一次
            //从map中获取指定key 的数据,如果不存在,就通过后面的方法创建并保存进去
            Object servlet = url2ServletMapping.computeIfAbsent(servletName, key -> {
                try {
                    return targetServletClass.newInstance();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
            //执行方法并获取结果
            Object result = targetServletClassMethod.invoke(servlet, req, resp);
            if (result instanceof String) {
                if (((String) result).startsWith(StringConstans.FORWARD)) {
                    //转发
                    req.getRequestDispatcher(((String) result).replace(StringConstans.FORWARD, "")).forward(req,resp);
                } else if (((String) result).startsWith(StringConstans.REDIRECT)) {
                    //重定向
                    resp.sendRedirect(((String) result).replace(StringConstans.REDIRECT, ""));
                }else{
                    //原始内容直接返回
                    resp.getWriter().write((String) result);
                }
            }
        } catch (Exception e) {
            //代表类不存在,其实就代表着这个请求地址不存在
            e.printStackTrace();
            resp.sendError(404);
        }

        System.err.println("servletName:=====>" + servletName);
    }
}
